package im.oen.boot.common.utils;

import im.oen.boot.common.constant.OenCode;
import im.oen.boot.common.data.StateBase;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 检查器
 *
 * @author Kevin.Xu
 */
public class Checker {

    private static final List<String> IMAGE_TYPES = Arrays.asList("bmp", "jpg", "png", "tif", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd", "cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "wmf", "webp");

    public static boolean isSuccess(StateBase obj) {
        return (obj != null && obj.isSuccess());
    }

    public static void asserts(StateBase obj) {
        if (!Checker.isSuccess(obj)) {
            throw OenCode.PARAMETER_ERROR.exception(JsonUtil.safeToJson(obj));
        }
    }

    public static void asserts(boolean result) {
        if (!result) {
            throw OenCode.PARAMETER_ERROR.exception();
        }
    }

    public static void asserts(Runner.FunctionWithAssert func) {
        if (func == null) {
            throw OenCode.PARAMETER_ERROR.exception();
        }

        if (!func.check()) {
            throw OenCode.PARAMETER_ERROR.exception();
        }
    }

    /**
     * 检查类型是否为图片类型
     *
     * @param type 类型信息 如: .jpg
     * @return 此类型是否为图片
     */
    public static boolean isImage(String type) {
        if (Checker.isEmpty(type)) {
            return false;
        }

        if (type.startsWith(".")) {
            type = type.substring(1);
        }
        type = type.trim().toLowerCase();
        return IMAGE_TYPES.contains(type);
    }

    /**
     * 区间
     *
     * @param source 源数据
     * @param max    最大值
     * @param min    最小值
     * @return 是否在此区间
     */
    public static boolean range(BigDecimal source, BigDecimal max, BigDecimal min) {
        if (source == null || max == null || min == null) {
            return false;
        }
        return (max.compareTo(source) == 1) && (source.compareTo(min) == 1);
    }

    /**
     * 大于
     *
     * @param one 数据1
     * @param two 数据2
     * @return 数据1 大于 数据2
     */
    public static boolean gt(BigDecimal one, BigDecimal two) {
        if (one == null) {
            return false;
        }
        if (two == null) {
            return true;
        }
        return one.compareTo(two) == 1;
    }

    /**
     * 大于等于
     *
     * @param one 数据1
     * @param two 数据2
     * @return 数据1 大于等于 数据2
     */
    public static boolean gte(BigDecimal one, BigDecimal two) {
        if (one == null) {
            return false;
        }
        if (two == null) {
            return true;
        }
        return one.compareTo(two) >= 0;
    }

    /**
     * 检查身份证是否格式正确
     *
     * @param idCard 18位身份证信息
     * @return
     */
    public static boolean validIdCard(String idCard) {
        if (idCard == null) {
            return false;
        }
        if (idCard.length() != 18) {
            return false;
        }
        char[] id = idCard.toCharArray();
        int i, sum, n;
        for (sum = i = 0; i < 17; i++) {
            sum += ((1 << (17 - i)) % 11) * (id[i] - '0');
        }
        n = (12 - (sum % 11)) % 11;
        if (n < 10) {
            return (n == id[17] - '0');
        } else {
            return (id[17] == 'X');
        }
    }

    /**
     * 彻底检查对象是否为空
     *
     * @param obj
     * @return
     */
    public static boolean isEmptyString(Object obj) {
        if (isEmpty(obj)) {
            return true;
        }
        if (isBaseType(obj)) {
            return isEmpty(String.valueOf(obj));
        }
        return isEmpty(JsonUtil.safeToJson(obj));
    }

    /**
     * 是否全部为空
     *
     * @param strs 字符串数组
     * @return 全部为空:true
     */
    public static boolean isAllEmpty(String... strs) {
        if (strs == null || strs.length == 0) {
            return true;
        }
        for (String str : strs) {
            if (Checker.isNotEmpty(str)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否存在为空的
     *
     * @param strs 字符串数组
     * @return 有为空的:true
     */
    public static boolean hasEmpty(String... strs) {
        if (strs == null || strs.length == 0) {
            return true;
        }
        for (String str : strs) {
            if (Checker.isEmpty(str)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isAllEmpty(Object... objs) {
        if (objs == null || objs.length == 0) {
            return true;
        }
        for (Object obj : objs) {
            if (Checker.isNotEmpty(obj)) {
                return false;
            }
        }
        return true;
    }

    public static boolean hasEmpty(Object... objs) {
        if (objs == null || objs.length == 0) {
            return true;
        }
        for (Object obj : objs) {
            if (Checker.isEmpty(obj)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isEmpty(String obj) {
        return obj == null || obj.trim().isEmpty() || obj.trim() == "";
    }

    public static boolean isNotEmpty(String obj) {
        return obj != null && !obj.isEmpty() && obj.trim() != "";
    }

    /**
     * @param <T>
     * @param list
     * @return
     */
    public static <T> boolean isEmpty(List<T> list) {
        return list == null || list.isEmpty();
    }

    /**
     * @param <T>
     * @param list
     * @return
     */
    public static <T> boolean isNotEmpty(List<T> list) {
        return list != null && !list.isEmpty();
    }

    /**
     * @param list
     * @param <T>
     * @return
     */
    public static <T> boolean isEmpty(Collection<T> list) {
        return list == null || list.isEmpty();
    }

    /**
     * @param list
     * @param <T>
     * @return
     */
    public static <T> boolean isNotEmpty(Collection<T> list) {
        return list != null && !list.isEmpty();
    }

    /**
     * @param <K>
     * @param <V>
     * @param map
     * @return
     */
    public static <K, V> boolean isEmpty(Map<K, V> map) {
        return map == null || map.isEmpty();
    }

    /**
     * @param <K>
     * @param <V>
     * @param map
     * @return
     */
    public static <K, V> boolean isNotEmpty(Map<K, V> map) {
        return map != null && !map.isEmpty();
    }

    /**
     * @param objs
     * @return
     */
    public static boolean isEmpty(Object[] objs) {
        return objs == null || objs.length == 0;
    }

    /**
     * 对象数组是否不为空
     *
     * @param objs 对象数组
     * @return
     */
    public static boolean isNotEmpty(Object[] objs) {
        return objs != null && objs.length > 0;
    }

    /**
     * 是否不为空
     *
     * @param obj 对象
     * @return obj != null
     */
    public static boolean isNotEmpty(Object obj) {
        return obj != null;
    }

    /**
     * 是否为空
     *
     * @param obj 对象
     * @return obj==null
     */
    public static boolean isEmpty(Object obj) {
        return obj == null;
    }

    /**
     * 是否是基础类型
     *
     * @return null is true
     */
    public static boolean isBaseType(Object obj) {
        if (obj instanceof Byte) {
            return true;
        }
        if (obj instanceof Short) {
            return true;
        }
        if (obj instanceof Double) {
            return true;
        }
        if (obj instanceof Integer) {
            return true;
        }
        if (obj instanceof Long) {
            return true;
        }
        if (obj instanceof Character) {
            return true;
        }
        if (obj instanceof Boolean) {
            return true;
        }
        if (obj instanceof String) {
            return true;
        }
        return false;
    }
}
